type Task = () => void;

class EventLoop {
  private taskQueue: Task[] = [];
  private microtaskQueue: Task[] = [];
  private isRunning: boolean = false;

  // 添加宏任务
  public addTask(task: Task) {
    this.taskQueue.push(task);
    this.runIfNeeded();
  }

  // 添加微任务
  public addMicrotask(task: Task) {
    this.microtaskQueue.push(task);
    this.runIfNeeded();
  }

  // 启动事件循环
  private runIfNeeded() {
    if (!this.isRunning) {
      this.isRunning = true;
      this.runLoop();
    }
  }

  // 事件循环核心逻辑
  private async runLoop() {
    while (this.taskQueue.length > 0 || this.microtaskQueue.length > 0) {
      // 1. 执行所有微任务
      while (this.microtaskQueue.length > 0) {
        const microtask = this.microtaskQueue.shift()!;
        microtask();
      }

      // 2. 执行一个宏任务
      if (this.taskQueue.length > 0) {
        const task = this.taskQueue.shift()!;
        task();

        // 模拟浏览器中的 UI 渲染时机
        await new Promise(resolve => setTimeout(resolve, 0));
      }
    }

    this.isRunning = false;
  }
}

// 使用示例
const eventLoop = new EventLoop();

// 添加宏任务
eventLoop.addTask(() => {
  console.log('宏任务 1 开始');
  
  // 在宏任务中添加微任务
  eventLoop.addMicrotask(() => {
    console.log('微任务 1 执行');
  });
  
  console.log('宏任务 1 结束');
});

// 添加另一个宏任务
eventLoop.addTask(() => {
  console.log('宏任务 2 开始');
  
  // 在宏任务中添加微任务
  eventLoop.addMicrotask(() => {
    console.log('微任务 2 执行');
  });
  
  console.log('宏任务 2 结束');
});

// 输出顺序：
// 宏任务 1 开始
// 宏任务 1 结束
// 微任务 1 执行
// 宏任务 2 开始
// 宏任务 2 结束
// 微任务 2 执行